﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.IO;
using System.Net;
using Microsoft.ApplicationServer.Caching;
using System.Data.SqlClient;
using System.Net.Mail;
using System.Net.Mime;

namespace WCFServiceWebRole1
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    public class Service1 : IService1
    {
        static DataCacheFactory _Factory = new DataCacheFactory();
        private static string conStr = "Data Source=csbz8q6qgy.database.windows.net; Initial Catalog=TravelOnTime; uid=Codeinstincts; Password=zk3zk3zk3!";
        private static SqlConnection con = new SqlConnection(conStr);
        //try
        //{
        //    con.Open();
        //}
        //catch (SqlException) { }
        //finally { con.Close(); }
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public void prepareToSendToast()
        {
            // for demo purpose, the following line is commented
            //for (int i = 0; i < 120; i++)
            //{
            //    System.Threading.Thread.Sleep(1000);
            //    //if (StoppHasBinPushed) break;
            //}

            foreach (string subscriptionUri in RetrieveToast())
            {
                try
                {
                    // Get the Uri that the Microsoft Push Notification Service returns to the Push Client when creating a notification channel.
                    // Normally, a web service would listen for Uri's coming from the web client and maintain a list of Uri's to send
                    // notifications out to.
                    //string subscriptionUri = "http://db3.notify.live.net/throttledthirdparty/01.00/AAGkDbaJfv8HTr6QBrbwo9_7AgAAAAADFAAAAAQUZm52OjFERUVGMjg3RjFGRTIyQTA";


                    HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);

                    // We will create a HTTPWebRequest that posts the toast notification to the Microsoft Push Notification Service.
                    // HTTP POST is the only allowed method to send the notification.
                    sendNotificationRequest.Method = "POST";

                    // The optional custom header X-MessageID uniquely identifies a notification message. 
                    // If it is present, the // same value is returned in the notification response. It must be a string that contains a UUID.
                    // sendNotificationRequest.Headers.Add("X-MessageID", "<UUID>");

                    // Create the toast message.
                    string toastMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                    "<wp:Notification xmlns:wp=\"WPNotification\">" +
                       "<wp:Toast>" +
                            "<wp:Text1>Travel On Time</wp:Text1>" +
                            "<wp:Text2>Rate our taxi driver now!</wp:Text2>" +
                            "<wp:Param>/Page2.xaml?NavigatedFrom=Toast Notification</wp:Param>" +
                       "</wp:Toast> " +
                    "</wp:Notification>";

                    // Sets the notification payload to send.
                    byte[] notificationMessage = Encoding.Default.GetBytes(toastMessage);

                    // Sets the web request content length.
                    sendNotificationRequest.ContentLength = notificationMessage.Length;
                    sendNotificationRequest.ContentType = "text/xml";
                    sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "toast");
                    sendNotificationRequest.Headers.Add("X-NotificationClass", "2");


                    using (Stream requestStream = sendNotificationRequest.GetRequestStream())
                    {
                        requestStream.Write(notificationMessage, 0, notificationMessage.Length);
                    }

                    // Send the notification and get the response.
                    HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();
                    string notificationStatus = response.Headers["X-NotificationStatus"];
                    string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
                    string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];

                    // Display the response from the Microsoft Push Notification Service.  
                    // Normally, error handling code would be here.  In the real world, because data connections are not always available,
                    // notifications may need to be throttled back if the device cannot be reached.
                    //TextBoxResponse.Text = notificationStatus + " | " + deviceConnectionStatus + " | " + notificationChannelStatus;
                }
                catch (Exception ex)
                {
                }
            }

            
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }

        public bool initCache()
        {
            bool success = false;
            var cache = _Factory.GetDefaultCache();
            CommentList cl = cache["CommentList"] as CommentList;
            if (cl == null)
            {
                var comList = new CommentList();
                try
                {
                    SqlCommand com = new SqlCommand("SELECT * FROM dbo.Comment", con);
                    con.Open();

                    SqlDataReader dr = com.ExecuteReader();
                    while (dr.Read())
                    {
                        comList.Add(
                            new Comment
                            {
                                CommentID = (int)dr["CommentID"],
                                CommentString = dr["CommentString"].ToString(),
                                ToastID = dr["ToastID"].ToString(),
                                DisplayName = dr["DisplayName"].ToString()
                            });
                    }
                    success = true;
                    cache["CommentList"] = comList;
                }
                catch (SqlException) { }
                finally { con.Close(); }
            }
            return success;
        }

        public Accnt LoginUser(string NRIC, string password)
        {
            //returns Role
            //string role = "";
            //try
            //{
            //    string cmd = "SELECT Role FROM dbo.Accnt WHERE NRIC=@NRIC AND Password=@Password";
            //    SqlCommand com = new SqlCommand(cmd, con);
            //    com.Parameters.AddWithValue("@NRIC", NRIC);
            //    com.Parameters.AddWithValue("@Password", password);
            //    con.Open();
            //    SqlDataReader dr = com.ExecuteReader();
            //    while (dr.Read())
            //    {
            //        role = dr["Role"].ToString();
            //    }
                
            //}
            //catch (SqlException) { }
            //finally { con.Close(); }

            Accnt a = new Accnt();
            try
            {
                string cmd = "SELECT * FROM dbo.Accnt WHERE NRIC=@NRIC AND Password=@Password";
                SqlCommand com = new SqlCommand(cmd, con);
                com.Parameters.AddWithValue("@NRIC", NRIC);
                com.Parameters.AddWithValue("@Password", password);
                con.Open();
                SqlDataReader dr = com.ExecuteReader();
                while (dr.Read())
                {
                    a.AccntID = (int)dr["AccntID"];
                    a.Name = dr["Name"].ToString();
                    a.Role = dr["Role"].ToString();
                    a.PlateNum = dr["PlateNum"].ToString();
                    a.LikesCount = (int)dr["LikesCount"];
                    a.NRIC = dr["NRIC"].ToString();
                    a.OperatingPlace = dr["OperatingPlace"].ToString();
                }
            }
            catch (SqlException) { }
            finally { con.Close(); }
            if (a.NRIC == null)
            {
                return null;
            }
            return a;
        }

        public CommentList RetrieveLatest8Comments()
        {
            //use cache to retrieve 8 latest
            var cache = _Factory.GetDefaultCache();
            CommentList cl = cache["CommentList"] as CommentList;
            var points = from ele in cl
                         orderby ele.CommentID descending
                         select ele;
            CommentList clReturn = new CommentList();
            int count = 0;
            foreach (Comment c in points)
            {
                if (count == 7)
                {
                    break;
                }
                else
                {
                    clReturn.Add(c);
                }
                count++;
            }
            return clReturn;
        }

        public bool InsertComment(string displayName, string comment, string toastID, byte[] commentImg, bool postToFacebook, string fbEmail)
        {
            bool success = false;
            int iden = 0;
            //cache comment after inserting successful
            try
            {
                string cmd = "INSERT INTO dbo.Comment (DisplayName, CommentString, ToastID, TimeLimit) VALUES (@displayName, @comment, @toastID, @TimeLimit); SELECT CommentID = SCOPE_IDENTITY()";
                SqlCommand com = new SqlCommand(cmd, con);
                if (!string.IsNullOrEmpty(displayName))
                {
                    com.Parameters.AddWithValue("@displayName", displayName);
                }
                else
                {
                    com.Parameters.AddWithValue("@displayName", "");
                }
                if (!string.IsNullOrEmpty(comment))
                {
                    com.Parameters.AddWithValue("@comment", comment);
                }
                else
                {
                    com.Parameters.AddWithValue("@comment", "");
                }
                if (!string.IsNullOrEmpty(toastID))
                {
                    com.Parameters.AddWithValue("@toastID", toastID);
                }
                else
                {
                    com.Parameters.AddWithValue("@toastID", "");
                }
                com.Parameters.AddWithValue("@TimeLimit", DateTime.UtcNow);
                con.Open();
                iden = com.ExecuteNonQuery();
                success = true;
            }
            catch (SqlException) { }
                catch (Exception) {}
            finally { con.Close(); }
            if (success)
            {
                if (commentImg != null)
                {
                    this.StoreImg(iden.ToString(), commentImg);
                }
                Comment c = new Comment();
                c.CommentID = iden;
                c.DisplayName = displayName;
                c.CommentString = comment;
                c.CommentImg = commentImg;
                c.ToastID = toastID;
                var cache = _Factory.GetDefaultCache();
                CommentList cl = cache["CommentList"] as CommentList;
                if (cl == null)
                {
                    cl = new CommentList();
                }
                cl.Add(c);
                cache["CommentList"] = cl;
                if (postToFacebook)
                {
                    PostToFB(fbEmail, commentImg, comment);
                }
            }
            return success;
        }

        public bool LikeDriver(string name, string plateNum)
        {
            bool success = false;
            try
            {
                string cmd = "UPDATE dbo.Accnt SET LikesCount=(LikesCount+1) WHERE Name=@n AND PlateNum=@pn";
                SqlCommand com = new SqlCommand(cmd, con);
                com.Parameters.AddWithValue("@n", name);
                com.Parameters.AddWithValue("@pn", plateNum);
                con.Open();
                com.ExecuteNonQuery();
                success = true;
            }
            catch (SqlException) { }
            finally { con.Close(); }
            return success;
        }

        public AccntList GetLeaderboard()
        {
            AccntList al = RetrieveDrivers();
            var drivers = from d in al
                          orderby d.LikesCount descending
                          select d;
            AccntList al2 = new AccntList();
            foreach (Accnt a in drivers)
            {
                al2.Add(a);
            }
            return al2;
        }

        public AccntList RetrieveDrivers()
        {
            AccntList al = new AccntList();
            try
            {
                string cmd = "SELECT * FROM dbo.Accnt WHERE Role='Driver'";
                SqlCommand com = new SqlCommand(cmd, con);
                con.Open();
                SqlDataReader dr = com.ExecuteReader();
                while (dr.Read())
                {
                    Accnt a = new Accnt();
                    a.AccntID = (int)dr["AccntID"];
                    a.Name = dr["Name"].ToString();
                    a.Role = dr["Role"].ToString();
                    a.PlateNum = dr["PlateNum"].ToString();
                    a.LikesCount = (int)dr["LikesCount"];
                    a.NRIC = dr["NRIC"].ToString();
                    a.OperatingPlace = dr["OperatingPlace"].ToString();
                    al.Add(a);
                }
            }
            catch (SqlException) { }
            finally { con.Close(); }
            return al;
        }

        public int RetrieveDriverLikes(int accntID)
        {
            int likes = -1;
            try
            {
                string cmd = "SELECT LikesCount FROM dbo.Accnt WHERE AccntID=@aid";
                SqlCommand com = new SqlCommand(cmd, con);
                com.Parameters.AddWithValue("@aid", accntID);
                con.Open();
                SqlDataReader dr = com.ExecuteReader();
                while (dr.Read())
                {
                    likes = (int)dr["LikesCount"];
                }
            }
            catch (SqlException) { }
            finally { con.Close(); }
            return likes;
        }

        public bool StoreImg(string fileName, byte[] comImg)
        {
            bool results = StorageRetainer.ImgStore(fileName, comImg);
            return results;
        }

        public byte[] RetrieveImg(string fileName)
        {
            byte[] img = StorageRetainer.ImgRetrieval(fileName);
            return img;
        }

        public bool RequestForQuotation(DateTime StartDate, string Address, string PickUpStop, string Frequency)
        {
            bool success = false;
            try
            {
                string cmd = "INSERT INTO dbo.Bid (NRIC, StartDate, Address, PickUpStop, Frequency, Amount) VALUES (@NRIC, @StartDate, @Address, @PickUpStop, @Frequency, @Amount)";
                SqlCommand com = new SqlCommand(cmd, con);
                com.Parameters.AddWithValue("@NRIC", "");
                com.Parameters.AddWithValue("@StartDate", StartDate);
                com.Parameters.AddWithValue("@Address", Address);
                com.Parameters.AddWithValue("@PickUpStop", PickUpStop);
                com.Parameters.AddWithValue("@Frequency", Frequency);
                com.Parameters.AddWithValue("@Amount", 0.0);
                con.Open();
                com.ExecuteNonQuery();
                success = true;
            }
            catch (SqlException) { }
            finally { con.Close(); }
            return success;
        }

        public bool PlaceBid(double Amount, int BidID)
        {
            bool success = false;
            try
            {
                string cmd = "UPDATE dbo.Bid SET Amount=@amt WHERE BidID=@bid";
                SqlCommand com = new SqlCommand(cmd, con);
                com.Parameters.AddWithValue("@amt", Amount);
                com.Parameters.AddWithValue("@bid", BidID);
                con.Open();
                com.ExecuteNonQuery();
                success = true;
            }
            catch (SqlException) { }
            finally { con.Close(); }
            return success;
        }

        public bool InsertToast(string toastID)
        {
             //string conStr = "Data Source=csbz8q6qgy.database.windows.net; Initial Catalog=TravelOnTime; uid=Codeinstincts; Password=zk3zk3zk3!";
       
             SqlConnection con1 = new SqlConnection(conStr);
            bool success = false;
            try
            {
                string cmd = "INSERT INTO dbo.ToastSub (ToastID) VALUES (@ToastID)";
                SqlCommand com = new SqlCommand(cmd, con1);
                com.Parameters.AddWithValue("@ToastID", toastID);
                con1.Open();
                com.ExecuteNonQuery();
                success = true;
            }
            catch (SqlException) { }
            finally { con1.Close(); }
            return success;
        }

        public List<string> RetrieveToast()
        {
            SqlConnection con1 = new SqlConnection(conStr);
            List<string> toasts = new List<string>();
            try
            {
                string cmd = "SELECT * FROM dbo.ToastSub";
                SqlCommand com = new SqlCommand(cmd, con1);
                con1.Open();
                SqlDataReader dr = com.ExecuteReader();
                while (dr.Read())
                {
                    string toast = dr["ToastID"].ToString();
                    toasts.Add(toast);
                }
            }
            catch (SqlException) { }
            finally { con1.Close(); }
            return toasts;
        }

        public void PostToFB(string fbEmail, byte[] comImg, string com)
        {
            com += " Posted from Travel On Time";
            try
            {
                SmtpClient sc = new SmtpClient();
                sc.EnableSsl = true;
                NetworkCredential basic = new NetworkCredential("Recyclocator@hotmail.com", "zk3zk3zk3");
                sc.Credentials = basic;
                MailMessage m = new MailMessage("Recyclocator@hotmail.com", fbEmail);
                m.Subject = com;
                Stream s = new MemoryStream(comImg);
                //ContentType ct = new ContentType("image/png");
                Attachment a = new Attachment(s, "ToTImg.jpeg", "image/png");
                m.Attachments.Add(a);
                sc.Send(m);
            }
            catch (Exception) { }
        }

    }
}
